package com.jgp.media.image;

import com.alibaba.simpleimage.ImageFormat;
import com.alibaba.simpleimage.ImageWrapper;
import com.alibaba.simpleimage.SimpleImageException;
import com.alibaba.simpleimage.analyze.search.cluster.impl.Point;
import com.alibaba.simpleimage.render.*;
import com.alibaba.simpleimage.util.*;
import org.apache.commons.lang3.StringUtils;

import javax.imageio.ImageIO;
import javax.media.jai.PlanarImage;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 项目   jgp-cloud-parent
 * 作者   loufei
 * 时间   2018/8/26
 */
public class ImageUtil{
    public static String WATER_IMAGE_URL = "D:\\img\\watermark.png";
    protected static ImageFormat outputFormat = ImageFormat.JPEG;
    
    public static void main(String[] args) {
        /*// 1.等比例缩放
         scaleNormal("D:\\img\\src.jpg", "D:\\img\\scaleNormal.jpg", 720,
         1080);
        // 2.等比例缩放加水印
         scaleWithWaterMark("D:\\img\\src.jpg",
         "D:\\img\\scaleWithWaterMark.jpg",720, 1080);
        // 3.缩放到指定宽度
         scaleWithWidth("D:\\img\\src.jpg", "D:\\img\\scaleWithWidth.jpg",
         400);
        // 4.缩放到指定高度
         scaleWithHeight("D:\\img\\src.jpg", "D:\\img\\scaleWithHeight.jpg",
         600);
        // 5.裁切成正方形
         cut("D:\\img\\src.jpg", "D:\\img\\cut.jpg");*/
        // 6.从中间裁切
        ImageWrapper imageWrapper = scaleWithWaterText("/Users/congcong/Public/projects/temp/jgp/sss.jpg","一二三三二一哈一二三三二一哈哈 2019/12/22哈哈 2019/12/22", 800, 900);
        ImageUtil.writeImage(imageWrapper,"/Users/congcong/Public/projects/temp/jgp/sss-1.jpg","jpg");
    }
    
    /**
     * @param pInput
     * @param pImgeFlag
     * @return
     * @throws Exception
     */
    public static boolean isPicture(String pInput, String pImgeFlag) throws Exception {
        if (StringUtils.isBlank(pInput)) {
            return false;
        }
        String tmpName = pInput.substring(pInput.lastIndexOf(".") + 1, pInput.length());
        String imgeArray[][] = {{"bmp", "0"}, {"dib", "1"}, {"gif", "2"}, {"jfif", "3"}, {"jpe", "4"},
                {"jpeg", "5"}, {"jpg", "6"}, {"png", "7"}, {"tif", "8"}, {"tiff", "9"}, {"ico", "10"}};
        for (int i = 0; i < imgeArray.length; i++) {
            if (!StringUtils.isBlank(pImgeFlag) && imgeArray[i][0]
                    .equals(tmpName.toLowerCase()) && imgeArray[i][1].equals(pImgeFlag)) {
                return true;
            }
            if (StringUtils.isBlank(pImgeFlag) && imgeArray[i][0].equals(tmpName.toLowerCase())) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * 等比例缩放 会裁切部分内容
     *
     * @param src
     * @param width
     * @param height
     */
    @SuppressWarnings("static-access")
    public static ImageWrapper scale(String src, int width, int height) {
        File in = new File(src); // 原图片
        try (
                FileInputStream inStream = new FileInputStream(in);
        ) {
            ImageWrapper imageWrapper = ImageReadHelper.read(inStream);
            
            int w = imageWrapper.getWidth();
            int h = imageWrapper.getHeight();
            
            float w1, h1;
            float sp = (float) w / h;
            float rp = (float) width / height;
            if (sp > rp) {
                w1 = (width * h) / (float) w;
                h1 = width;
                
            } else if (sp < rp) {
                h1 = (height * w) / (float) h;
                w1 = width;
            } else {
                w1 = width;
                h1 = height;
            }
            // 1.缩放
            ScaleParameter scaleParam = new ScaleParameter(
                    (int) w1, (int) h1, ScaleParameter.Algorithm.LANCZOS); // 缩放参数
            PlanarImage planrImage = ImageScaleHelper.scale(imageWrapper.getAsPlanarImage(), scaleParam);
            return new ImageWrapper(planrImage);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SimpleImageException e) {
        
        }
        return null;
    }
    
    public static ImageWrapper scaleNormal(String src, int width, int height) {
        File in = new File(src); // 原图片
        try (
                FileInputStream inStream = new FileInputStream(in);
        ) {
            ImageWrapper imageWrapper = ImageReadHelper.read(inStream);
            int w = imageWrapper.getWidth();
            int h = imageWrapper.getHeight();
            int cw = w, ch = h, x = 0, y = 0;
            boolean isDeal = true;
            if (height > h || width > w) {
                isDeal = false;
            } else if ((w - width) > (h - height)) {
                ch = h;
                double per1 = new BigDecimal((float)width / height).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                double per2 = new BigDecimal((float)height /width ).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                cw = (int)(h * per1);
                x = (w - cw) / 2;
                if (cw > h) {
                    cw = w;
                    ch = (int)(w * per2);
                    y = (h - ch) / 2;
                    x = 0;
                }
                
            } else if ((w - width) <= (h - height)) {
                cw = w;
                double per1 = new BigDecimal((float)height / width).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                double per2 = new BigDecimal((float)width / height).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                ch = (int)(w * per1);
                y = (h - ch) / 2;
                if (ch > h) {
                    ch = h;
                    cw = (int)(h * per2);
                    x = (w - cw) / 2;
                    y = 0;
                }
            }
            System.out.println("x: " + x + ", y:" + y + ", cw: " + cw + ",ch:" + ch + "");
            if (isDeal) {
                CropParameter cropParam = new CropParameter(x, y, cw, ch);// 裁切参数
                PlanarImage planarImage = ImageCropHelper.crop(imageWrapper.getAsPlanarImage(), cropParam);
                ScaleParameter scaleParam = new ScaleParameter(
                        width, height, ScaleParameter.Algorithm.LANCZOS); // 缩放参数
                planarImage = ImageScaleHelper.scale(planarImage, scaleParam);
                
                
                imageWrapper = new ImageWrapper(planarImage);
            }
            return imageWrapper;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SimpleImageException e) {
        }
        return null;
    }
    
    /**
     * 压缩图片到 指定尺寸,图片比目标图片小则不会变形(有水印）
     *
     * @param src
     * @param waterPic
     * @param width
     * @param height
     */
    public static ImageWrapper scaleWithWaterPic(String src,String waterPic, int width, int height) {
        try {
            ImageWrapper imageWrapper = scaleNormal(src, width, height);
            // 3.打水印
            BufferedImage waterImage = ImageIO.read(new File(WATER_IMAGE_URL));
            ImageWrapper waterWrapper = new ImageWrapper(waterImage);
            Point p = calculate(imageWrapper.getWidth(), imageWrapper.getHeight(), waterWrapper.getWidth(),
                                waterWrapper.getHeight()
            );
            WatermarkParameter param = new WatermarkParameter(
                    waterWrapper, 1f, (int) p.getX(), (int) p.getY());
            BufferedImage bufferedImage = ImageDrawHelper
                    .drawWatermark(imageWrapper.getAsBufferedImage(), param);
            return new ImageWrapper(bufferedImage);
            
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    
    /**
     * 压缩图片到 指定尺寸,图片比目标图片小则不会变形(有水印）
     *
     * @param src
     * @param waterText
     * @param width
     * @param height
     */
    public static ImageWrapper scaleWithWaterText(String src,String waterText, int width, int height) {
        ImageWrapper imageWrapper = scale(src, width, height);
    
        BufferedImage bufferedImage = imageWrapper.getAsBufferedImage();
        // 3.打水印
        CornerDrawTextItem item1 = new CornerDrawTextItem(waterText,
                                                          Color.black,
                                                          Color.white,
                                                          new Font("宋体", Font.BOLD, 12),
                                                          6, 1f);
        List<DrawTextItem> textItemList = new ArrayList<>();
        textItemList.add(item1);
        DrawTextParameter param = new DrawTextParameter(textItemList);
        ImageDrawHelper.drawText(bufferedImage,param);
        return new ImageWrapper(bufferedImage);
    }
    
    static ImageWrapper locateTxt(BufferedImage src, String txt) throws IOException, SimpleImageException {
        Graphics2D g2 = src.createGraphics();
        
        g2.setColor(Color.red);
        g2.setFont(new Font("宋体", Font.BOLD, 25));
        g2.drawString(txt, 100, 200);
        
        g2.dispose();
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(src, "png", os);
        InputStream is = new ByteArrayInputStream(os.toByteArray());
        ImageWrapper iw = ImageReadHelper.read(is);
        if(is != null) {
            is.close();
        }
        return iw;
    }
    
    
    public static void writeImage(ImageWrapper imageWrapper, String target, String prefix) {
        try (
                FileOutputStream outStream = new FileOutputStream(target)
        ) {
            
            ImageWriteHelper.write(imageWrapper, outStream, outputFormat.getImageFormat(prefix),
                                   new WriteParameter()
            );
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SimpleImageException e) {
        }
        
    }
    
    /**
     * 缩放到指定宽度 高度自适应
     *
     * @param src
     * @param width
     */
    @SuppressWarnings("static-access")
    public static ImageWrapper scaleWithWidth(String src, Integer width) {
        File in = new File(src); // 原图片
        try (
                FileInputStream inStream = new FileInputStream(in);
        ) {
            ImageWrapper imageWrapper = ImageReadHelper.read(inStream);
            
            int w = imageWrapper.getWidth();
            int h = imageWrapper.getHeight();
            // 1.缩放
            ScaleParameter scaleParam = new ScaleParameter(w, h, ScaleParameter.Algorithm.LANCZOS); // 缩放参数
            if (w < width) {// 如果图片宽和高都小于目标图片则不做缩放处理
                scaleParam = new ScaleParameter(w, h, ScaleParameter.Algorithm.LANCZOS);
            } else {
                int newHeight = getHeight(w, h, width);
                scaleParam = new ScaleParameter(width, newHeight + 1, ScaleParameter.Algorithm.LANCZOS);
            }
            PlanarImage planrImage = ImageScaleHelper.scale(imageWrapper.getAsPlanarImage(), scaleParam);
            return new ImageWrapper(planrImage);
            
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SimpleImageException e) {
        }
        return null;
    }
    
    /**
     * 缩放到指定高度，宽度自适应
     *
     * @param src
     * @param height
     */
    public static ImageWrapper scaleWithHeight(String src, Integer height) {
        File in = new File(src); // 原图片
        try (
                FileInputStream inStream = new FileInputStream(in);
        ) {
            ImageWrapper imageWrapper = ImageReadHelper.read(inStream);
            
            int w = imageWrapper.getWidth();
            int h = imageWrapper.getHeight();
            // 1.缩放
            ScaleParameter scaleParam = new ScaleParameter(w, h, ScaleParameter.Algorithm.LANCZOS); // 缩放参数
            if (w < height) {// 如果图片宽和高都小于目标图片则不做缩放处理
                scaleParam = new ScaleParameter(w, h, ScaleParameter.Algorithm.LANCZOS);
                
            } else {
                int newWidth = getWidth(w, h, height);
                scaleParam = new ScaleParameter(newWidth + 1, height, ScaleParameter.Algorithm.LANCZOS);
                
            }
            PlanarImage planarImage = ImageScaleHelper.scale(imageWrapper.getAsPlanarImage(), scaleParam);
            return new ImageWrapper(planarImage);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SimpleImageException e) {
        }
        return null;
    }
    
    /**
     * 根据宽、高和目标宽度 等比例求高度
     *
     * @param w
     * @param h
     * @param width
     * @return
     */
    public static Integer getHeight(Integer w, Integer h, Integer width) {
        
        return h * width / w;
    }
    
    /**
     * 根据宽、高和目标高度 等比例求宽度
     *
     * @param w
     * @param h
     * @param height
     * @return
     */
    public static Integer getWidth(Integer w, Integer h, Integer height) {
        return w * height / h;
    }
    
    /**
     * 从中间裁切需要的大小
     *
     * @param src
     * @param width
     * @param height
     */
    @SuppressWarnings("static-access")
    public static ImageWrapper cutCenter(String src, Integer width, Integer height) {
        File in = new File(src); // 原图片
        try (
                FileInputStream inStream = new FileInputStream(in);
        ) {
            ImageWrapper imageWrapper = ImageReadHelper.read(inStream);
            
            int w = imageWrapper.getWidth();
            int h = imageWrapper.getHeight();
            
            int x = (w - width) / 2;
            
            int y = (h - height) / 2;
            
            CropParameter cropParam = new CropParameter(x, y, width, height);// 裁切参数
            if (x < 0 || y < 0) {
                cropParam = new CropParameter(0, 0, w, h);// 裁切参数
                
            }
            PlanarImage planarImage = ImageCropHelper.crop(imageWrapper.getAsPlanarImage(), cropParam);
            return new ImageWrapper(planarImage);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SimpleImageException e) {
        }
        return null;
    }
    
    /**
     * 裁切 为正文形
     *
     * @param src
     */
    public static ImageWrapper cut(String src) {
        File in = new File(src); // 原图片
        try (
                FileInputStream inStream = new FileInputStream(in);
        ) {
            ImageWrapper imageWrapper = ImageReadHelper.read(inStream);
            
            int w = imageWrapper.getWidth();
            int h = imageWrapper.getHeight();
            int width = 0;
            int height = 0;
            
            if (w >= h) {
                width = h;
                height = h;
            } else {
                width = w;
                height = w;
            }
            CropParameter cropParam = new CropParameter(0, 0, width, height);// 裁切参数
            PlanarImage planrImage = ImageCropHelper.crop(imageWrapper.getAsPlanarImage(), cropParam);
            return new ImageWrapper(planrImage);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SimpleImageException e) {
        }
        return null;
    }
    
    public static Point calculate(int enclosingWidth, int enclosingHeight, int width, int height) {
        int x = (enclosingWidth / 2) - (width / 2);
        int y = (enclosingHeight / 2) - (height / 2);
        return new Point(x, y);
    }
    
    
    public static void start(Runnable runnable){
        runnable.run();
    }
    
}
